/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Robert M. Fuhrer (rfuhrer@watson.ibm.com), IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets; import java.util.Iterator; import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType; import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType; import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes; public class SuperTypesOfSingleton extends TypeSet { /** * The "base type" defining the lower bound of this set. */ private TType fLowerBound; SuperTypesOfSingleton(TType t, TypeSetEnvironment typeSetEnvironment) { super(typeSetEnvironment); fLowerBound= t; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse() */ @Override public boolean isUniverse() { return false; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone() */ @Override public TypeSet makeClone() { return this; //new SuperTypesOfSingleton(fLowerBound, getTypeSetEnvironment()); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#intersectedWith(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet) */ @Override protected TypeSet specialCasesIntersectedWith(TypeSet other) { if (other.isSingleton() && other.anyMember().equals(fLowerBound)) return other; // xsect(superTypes(A),A) = A if (other instanceof SuperTypesOfSingleton) { SuperTypesOfSingleton otherSuper= (SuperTypesOfSingleton) other; if (TTypes.canAssignTo(otherSuper.fLowerBound, fLowerBound)) return this; if (TTypes.canAssignTo(fLowerBound, otherSuper.fLowerBound)) return otherSuper; } else if (other.hasUniqueUpperBound()) { TType otherUpper= other.uniqueUpperBound(); if (otherUpper.equals(fLowerBound)) return new SingletonTypeSet(fLowerBound, getTypeSetEnvironment()); if ((otherUpper != fLowerBound && TTypes.canAssignTo(otherUpper, fLowerBound)) || ! TTypes.canAssignTo(fLowerBound, otherUpper)) return getTypeSetEnvironment().getEmptyTypeSet(); } // else if (other instanceof SuperTypesSet) { // SuperTypesSet otherSub= (SuperTypesSet) other; // TypeSet otherLowers= otherSub.lowerBound(); // // for(Iterator iter= otherLowers.iterator(); iter.hasNext(); ) { // TType t= (TType) iter.next(); // // if () // } // } return null; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty() */ @Override public boolean isEmpty() { return false; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound() */ @Override public TypeSet upperBound() { return new SingletonTypeSet(getJavaLangObject(), getTypeSetEnvironment()); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound() */ @Override public TypeSet lowerBound() { return new SingletonTypeSet(fLowerBound, getTypeSetEnvironment()); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound() */ @Override public boolean hasUniqueLowerBound() { return true; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound() */ @Override public boolean hasUniqueUpperBound() { return true; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound() */ @Override public TType uniqueLowerBound() { return fLowerBound; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound() */ @Override public TType uniqueUpperBound() { return getJavaLangObject(); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#superTypes() */ @Override public TypeSet superTypes() { return this; // makeClone(); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(TType) */ @Override public boolean contains(TType t) { if (t.equals(fLowerBound)) return true; if (t.equals(getJavaLangObject())) return true; return TTypes.canAssignTo(fLowerBound, t); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet) */ @Override public boolean containsAll(TypeSet other) { // Optimization: if other is also a SubTypeOfSingleton, just compare bounds if (other instanceof SuperTypesOfSingleton) { SuperTypesOfSingleton otherSuper= (SuperTypesOfSingleton) other; return TTypes.canAssignTo(fLowerBound, otherSuper.fLowerBound); } // Optimization: if other is a SubTypesSet, just compare all its bounds to mine if (other instanceof SuperTypesSet) { SuperTypesSet otherSuper= (SuperTypesSet) other; TypeSet otherLowerBounds= otherSuper.lowerBound(); for(Iterator<TType> iter= otherLowerBounds.iterator(); iter.hasNext(); ) { TType t= iter.next(); if (! TTypes.canAssignTo(fLowerBound, t)) return false; } return true; } if (other.isUniverse()) { return false; } // For now, no more tricks up my sleeve; get an iterator for(Iterator<TType> iter= other.iterator(); iter.hasNext(); ) { TType t= iter.next(); if (! TTypes.canAssignTo(fLowerBound, t)) return false; } return true; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator() */ @Override public Iterator<TType> iterator() { return enumerate().iterator(); // return new Iterator() { // // First type returned is fLowerBound, then each of the supertypes, in turn // // // // If the lower bound is an array type, return the set of array types // // { Array(superType(elementTypeOf(fUpperBound))) } // boolean isArray= (fLowerBound instanceof ArrayType); // private Set/*<TType>*/ superTypes= sTypeHierarchy.getAllSupertypes(getElementTypeOf(fLowerBound)); // private Iterator/*<TType>*/ superTypeIter= superTypes.iterator(); // private int nDims= getDimsOf(fLowerBound); // private int idx= (isArray ? -2 : -1); // public void remove() { /*do nothing*/ } // public boolean hasNext() { return idx < superTypes.size(); } // public Object next() { // int i=idx++; // if (i < -1) return sJavaLangObject; // if (i < 0) return fLowerBound; // return makePossiblyArrayTypeFor((TType) superTypeIter.next(), nDims); // } // }; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton() */ @Override public boolean isSingleton() { // The only thing that doesn't have at least 1 proper supertype is java.lang.Object return fLowerBound.equals(getJavaLangObject()); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember() */ @Override public TType anyMember() { return fLowerBound; } private EnumeratedTypeSet fEnumCache= null; /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate() */ @Override public EnumeratedTypeSet enumerate() { if (fEnumCache == null) { if (fLowerBound instanceof ArrayType) { ArrayType at= (ArrayType) fLowerBound; fEnumCache= EnumeratedTypeSet.makeArrayTypesForElements(TTypes.getAllSuperTypesIterator(at.getComponentType()), getTypeSetEnvironment()); fEnumCache.add(getJavaLangObject()); } else fEnumCache= new EnumeratedTypeSet(TTypes.getAllSuperTypesIterator(fLowerBound), getTypeSetEnvironment()); fEnumCache.add(fLowerBound); fEnumCache.initComplete(); } return fEnumCache; } @Override public boolean equals(Object o) { if (!(o instanceof SuperTypesOfSingleton)) return false; SuperTypesOfSingleton other= (SuperTypesOfSingleton) o; return other.fLowerBound.equals(fLowerBound); } @Override public int hashCode() { return fLowerBound.hashCode(); } @Override public String toString() { return "<" + fID + ": superTypes(" + fLowerBound.getPrettySignature() + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } }